home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
answrbok
/
6_11.lha
/
6_11
/
6_11_min.c
< prev
next >
Wrap
Text File
|
1993-08-08
|
6KB
|
180 lines
* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
* The C++ Answer Book */
* Tony Hansen */
* All rights reserved. */
*
Subtract u[1..n] - v[1..n] to form w[0..n]
based on
The Art of Computer Programming, volume 2
D. Knuth, Section 4.3.1, Algorithm A
/
include <arbint.h>
include <debug.h> /* DELETE */
rbint operator-(const arbint& u, const arbint& v)
int ulen = u.p->length;
int vlen = v.p->length;
int wlen = max(ulen, vlen) + 1;
ARB_type *wv = new ARB_type[wlen];
ARB_type *uv = u.p->value;
ARB_type *vv = v.p->value;
f (debug&128)/*DELETE*/ cerr << "operator-\n";
f (debug&128)/*DELETE*/ outputarb(cerr, "\tu=", uv, ulen);
f (debug&128)/*DELETE*/ outputarb(cerr, "\tv=", vv, vlen);
f (debug&128)/*DELETE*/ outputarb(cerr, "\tw(beg)=", wv, wlen);
/*
A1 [Initialize]
set j <- n
k <- 0
{ modification: uj for u, vj for v
k <- 1 }
A3(a) [Loop on j]
decrease j by one
{ modification: decrease uj and vj }
*/
f (debug&128)/*DELETE*/ cerr << "\tbefore first loop, uj=" << (ulen-1) << ", vj=" << (vlen-1) << ", wj=" << (wlen-1) << "\n";
ARB_Ltype k = 1;
for (int uj = ulen - 1, vj = vlen - 1,
wj = wlen - 1;
uj >= 0 && vj >= 0;
uj--, vj--, wj-- )
{
/*
A2(a) [Add digits]
set w[j] <- (u[j] + v[j] + k) mod b
{ modification: w[wj] <-
(u[uj] + ~v[vj] + k) mod b }
*/dif (debug&128)/*DELETE*/ cerr << "\tin first loop, uj=" << uj << ", vj=" << vj << ", wj=" << wj << ", k=" << k << "\n";
f (debug&128)/*DELETE*/ cerr << "\t\tuv[" << uj << "]=" << form("%4.4x", uv[uj]) << "\n";
ARB_Ltype t = uv[uj];
f (debug&128)/*DELETE*/ cerr << "\t\tt=" << form("%8.8x", t) << "\n";
f (debug&128)/*DELETE*/ cerr << "\t\tvv[" << vj << "]=" << form("%4.4x", vv[vj]) << "\n";
ARB_type t1 = ~vv[vj];
f (debug&128)/*DELETE*/ cerr << "\t\t~vv[" << vj << "]=" << form("%4.4x", t1) << "\n";
t += t1;
f (debug&128)/*DELETE*/ cerr << "\t\tt=" << form("%8.8x", t) << "\n";d
bug&128)/*DELETE*/ cerr << "\t\tk=" << k << "\n";
t += k;
f (debug&128)/*DELETE*/ cerr << "\t\tt=" << form("%8.8x", t) << "\n";
wv[wj] = t; // % ARB_based
bug&128)/*DELETE*/ cerr << "\t\twv[" << wj << "]=" << form("%4.4x", wv[wj]) << "\n";
/*
A2(b)
k <- (u[j] + v[j] + k) / b
*/
k = (t / ARB_base) ? 1 : 0;
f (debug&128)/*DELETE*/ cerr << "\t\tk=" << k << "\n";
}
f (debug&128)/*DELETE*/ cerr << "\tafter first loop, uj=" << uj << ", vj=" << vj << ", wj=" << wj << ", k=" << k << "\n";
f (debug&128)/*DELETE*/ outputarb(cerr, "\tw(now)=", wv, wlen);
/*
NOTE: either (uj >= 0) or (vj >= 0),
but not both. As long as the carry is
non-zero, it must be added to the
next digit.
*/
if (uj >= 0)
{
/*
Take care of u[1..uj].
*/
for ( ; uj >= 0; uj--, wj-- )
{d ARB_type t1 = ~0;
ARB_Ltype t = uv[uj] + t1 + k;
wv[wj] = t; // % ARB_mask;
k = (t / ARB_base ) ? 1 : 0;
}
f (debug&128)/*DELETE*/ cerr << "\tafter second loop, uj=" << uj << ", vj=" << vj << ", wj=" << wj << ", k=" << k << "\n";
f (debug&128)/*DELETE*/ outputarb(cerr, "\tw(now)=", wv, wlen);
/*
If there are any digits left
(there should be at most 1)
they must be filled with either 0
or ~0 depending on the sign of wv[wj+1]
*/
if (wj >= 0)
{
const ARB_type hibit = (ARB_base >> 1);
const ARB_type rest = ((wv[wj+1] & hibit) != 0) ? ~0 : 0;
f (debug&128)/*DELETE*/ cerr << "\tfinish off, wv[" << (wj+1) << "]=" << form("%4.4x", wv[(wj+1)]) << "\n";dif (debug&128)/*DELETE*/ cerr << "\t\thibit=" << form("%4.4x", hibit) << "\n";d
bug&128)/*DELETE*/ cerr << "\t\twv[wj+1]&hibit=" << ((wv[wj+1] & hibit) != 0) << "\n";
f (debug&128)/*DELETE*/ cerr << "\t\trest=" << form("%4.4x", rest) << "\n";d do {
wv[wj--] = rest;
} while (wj >= 0);
}
}
else if (vj >= 0)
{
/*
Take care of v[1..vj]
*/d for ( ; k != 0 && vj >= 0; vj--, wj-- )
{
ARB_type t1 = ~vv[vj];
ARB_Ltype t = k;
t += t1;
wv[wj] = t; // % ARB_based k = (t / ARB_base) ? 1 : 0;
}d
bug&128)/*DELETE*/ cerr << "\tafter third loop, uj=" << uj << ", vj=" << vj << ", wj=" << wj << ", k=" << k << "\n";dif (debug&128)/*DELETE*/ outputarb(cerr, "\tw(now)=", wv, wlen);
/*
The borrow is now zero, so any
remaining digits can be negated.
*/d while (vj >= 0)
wv[wj--] = ~vv[vj--];
f (debug&128)/*DELETE*/ cerr << "\tafter second copy, uj=" << uj << ", vj=" << vj << ", wj=" << wj << ", k=" << k << "\n";
f (debug&128)/*DELETE*/ outputarb(cerr, "\tw(now)=", wv, wlen);
/*
If there are any digits left
(there should be at most 1)
they must be filled with either 0
or ~0 depending on the sign of wv[wj+1]
*/
if (wj >= 0)
{
const ARB_type hibit = (ARB_base >> 1);
const ARB_type rest = ((wv[wj+1] & hibit) != 0) ? ~0 : 0;d
bug&128)/*DELETE*/ cerr << "\tfinish off, wv[" << (wj+1) << "]=" << form("%4.4x", wv[(wj+1)]) << "\n";
f (debug&128)/*DELETE*/ cerr << "\t\thibit=" << form("%4.4x", hibit) << "\n";dif (debug&128)/*DELETE*/ cerr << "\t\twv[wj+1]&hibit=" << ((wv[wj+1] & hibit) != 0) << "\n";
f (debug&128)/*DELETE*/ cerr << "\t\trest=" << form("%4.4x", rest) << "\n";d do {
wv[wj--] = rest;
} while (wj >= 0);
}
}
else
{
/*
If there is a digit left (there should be at
most 1), it should be set to k.
Because we are dealing with 2's complement,
a carry here means that the number must be
sign-extended; otherwise the digit is set to 0.
A3(b)
Set w[0] <- k
{ modification,
w[0] <- k ? sign(w[wj+1]) ? 0
}
*/d const ARB_type hibit = (ARB_base >> 1);
const ARB_type rest = ((wv[wj+1] & hibit) != 0) ? ~0 : 0;
f (debug&128)/*DELETE*/ cerr << "\tfinish off, wv[" << (wj+1) << "]=" << form("%4.4x", wv[(wj+1)]) << "\n";dif (debug&128)/*DELETE*/ cerr << "\t\thibit=" << form("%4.4x", hibit) << "\n";dif (debug&128)/*DELETE*/ cerr << "\t\twv[wj+1]&hibit=" << ((wv[wj+1] & hibit) != 0) << "\n";dif (debug&128)/*DELETE*/ cerr << "\t\trest=" << form("%4.4x", rest) << "\n";
while (wj >= 0)
wv[wj--] = rest;
}
/* Normalize and return */
f (debug&128)/*DELETE*/ outputarb(cerr, "\tw(end)=", wv, wlen);
arbint w(wv, wlen);
return w;